package com.atguigu.gulimall.order.config;

import com.atguigu.gulimall.order.entity.OrderEntity;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MyMQConfig {

    /**
     * ①通过调用api创建，见：test测试类下：com.atguigu.gulimall.order.GulimallOrderApplicationTests
     * ②spring支持直接以组件的方式自动创建：交换机Exchange、队列Queue、绑定关系Binding
     *      （前提是RabbitMQ中没有相同组件,有相同的不会创建，也不会覆盖）
     */

    /**
     * 创建队列①
     *
     * @return
     */
    @Bean
    public Queue orderDelayQueue() {
        /**
         * 1、设置队列的属性
         */
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", "order-event-exchange"); //x-dead-letter-exchange属性：当该队列出现死信时不丢弃，而是转发给指定的交换机：order-event-exchange
        arguments.put("x-dead-letter-routing-key", "order.release.order"); //x-dead-letter-routing-key属性：被转发的死信会携带该新路由键：order.release.order
        arguments.put("x-message-ttl", 60000); //x-message-ttl属性：该队列内消息的统一过期时间，单位毫秒
        /**
         * 2、创建该队列
         * 参数1：队列名字
         * 参数2：是否持久化
         * 参数3：是否排他
         * 参数4：是否自动删除
         * 参数5：该队列的属性
         */
        Queue queue = new Queue("order.delay.queue", true, false, false, arguments);
        return queue;
    }

    /**
     * 创建队列②
     *
     * @return
     */
    @Bean
    public Queue orderReleaseOrderQueue() {
        /**
         * 1、直接创建该队列，没有属性
         * 参数1：队列名字
         * 参数2：是否持久化
         * 参数3：是否排他
         * 参数4：是否自动删除
         * 参数5：该队列的属性（无属性）
         */
        Queue queue = new Queue("order.release.order.queue", true, false, false);
        return queue;
    }

    /**
     * 创建交换机
     *
     * @return
     */
    @Bean
    public Exchange orderEventExchange() {
        /**
         * 参数1：交换机名字
         * 参数2：是否持久化
         * 参数3：是否自动删除
         * 参数4：该交换机属性（无）
         */
        TopicExchange topicExchange = new TopicExchange("order-event-exchange", true, false);
        return topicExchange;
    }

    /**
     * 绑定关系①
     */
    @Bean
    public Binding orderCreateOrderBingding() {
        /**
         * 参数1：目的地的名字
         * 参数2：目的地类型 （交换机可以与队列或交换机绑定）
         * 参数3：交换机的名字
         * 参数4：路由键
         * 参数5：参数
         * 将交换机与目的地绑定，路由键是...
         */
        Binding binding = new Binding("order.delay.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.create.order",
                null);
        return binding;
    }

    /**
     * 绑定关系②
     *
     * @return
     */
    @Bean
    public Binding orderReleaseOrderBingding() {
        /**
         * 参数1：目的地的名字
         * 参数2：目的地类型 （交换机可以与队列或交换机绑定）
         * 参数3：交换机的名字
         * 参数4：路由键
         * 参数5：参数
         * 将交换机与目的地绑定，路由键是...
         */
        Binding binding = new Binding("order.release.order.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.release.order",
                null);
        return binding;
    }

    /**
     * 绑定关系③
     */
    @Bean
    public Binding orderReleaseOtherBinding(){
        /**
         * 参数1：目的地的名字
         * 参数2：目的地类型 （交换机可以与队列或交换机绑定）
         * 参数3：交换机的名字
         * 参数4：路由键
         * 参数5：参数
         * 将交换机与目的地绑定，路由键是...
         */
        Binding binding = new Binding("order.release.stock.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.release.order.#",
                null);
        return binding;
    }

    /**
     * 创建队列
     */
    @Bean
    public Queue orderSeckillOrderQueue(){
        Queue queue = new Queue("order.seckill.order.queue", true, false, false);
        return queue;
    }

    @Bean
    public Binding orderSeckillOrderQueueBinding(){
        Binding binding = new Binding("order.seckill.order.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.seckill.order",
                null);
        return binding;
    }



    /**
     * 测试：
     *    监听队列，接受消息
     */
//    @RabbitListener(queues = {"order.release.order.queue"})
    public void Listener(Message message,OrderEntity entity, Channel channel) throws IOException {
        System.out.println("收到过期的订单消息：准备关闭该订单"+entity);
        //手动ack （配置中关闭了自动ack，必须手动）
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }



}
